//
// Created by wangw on 2025/2/23.
//

#include <iostream>
#include <winsock2.h>
#include <ws2tcpip.h>

#pragma comment(lib, "ws2_32.lib") // 链接 Winsock 库

const int PORT = 8088;
const int BUFFER_SIZE = 1024;

class TCPServer {
public:
    TCPServer() : server_fd(INVALID_SOCKET) {}

    ~TCPServer() {
        stop();
    }

    bool start() {
        if (!initWinsock()) return false;
        if (!createSocket()) return false;
        if (!bindSocket()) return false;
        if (!listenForConnections()) return false;
        return true;
    }

    void run() {
        std::cout << "Waiting for a connection..." << std::endl;
        SOCKET new_socket = acceptConnection();
        if (new_socket == INVALID_SOCKET) return;

        std::cout << "Connection established" << std::endl;
        handleClient(new_socket);
    }

    void stop() {
        if (server_fd != INVALID_SOCKET) {
            closesocket(server_fd);
            server_fd = INVALID_SOCKET;
        }
        WSACleanup();
    }

private:
    SOCKET server_fd;

    bool initWinsock() {
        WSADATA wsaData;
        if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
            std::cerr << "WSAStartup failed: " << WSAGetLastError() << std::endl;
            return false;
        }
        return true;
    }

    bool createSocket() {
        server_fd = socket(AF_INET, SOCK_STREAM, 0);
        if (server_fd == INVALID_SOCKET) {
            std::cerr << "Socket creation failed: " << WSAGetLastError() << std::endl;
            return false;
        }
        return true;
    }

    bool bindSocket() {
        sockaddr_in address;
        address.sin_family = AF_INET;
        address.sin_addr.s_addr = INADDR_ANY;
        address.sin_port = htons(PORT);

        if (bind(server_fd, (sockaddr*)&address, sizeof(address)) == SOCKET_ERROR) {
            std::cerr << "Bind failed: " << WSAGetLastError() << std::endl;
            return false;
        }
        return true;
    }

    bool listenForConnections() {
        if (listen(server_fd, 3) == SOCKET_ERROR) {
            std::cerr << "Listen failed: " << WSAGetLastError() << std::endl;
            return false;
        }
        return true;
    }

    SOCKET acceptConnection() {
        sockaddr_in client_addr;
        int client_addrlen = sizeof(client_addr);
        SOCKET new_socket = accept(server_fd, (sockaddr*)&client_addr, &client_addrlen);
        if (new_socket == INVALID_SOCKET) {
            std::cerr << "Accept failed: " << WSAGetLastError() << std::endl;
        }
        return new_socket;
    }

    void handleClient(SOCKET client_socket) {
        char buffer[BUFFER_SIZE];
        while (true) {
            memset(buffer, 0, BUFFER_SIZE);
            int valread = recv(client_socket, buffer, BUFFER_SIZE, 0);
            if (valread <= 0) {
                std::cout << "Client disconnected" << std::endl;
                break;
            }
            std::cout << "Client: " << buffer << std::endl;

            std::string response;
            std::cout << "Server: ";
            std::getline(std::cin, response);
            send(client_socket, response.c_str(), response.length(), 0);
        }
        closesocket(client_socket);
    }
};

int main() {
    TCPServer server;
    if (!server.start()) {
        return -1;
    }
    server.run();
    server.stop();
    return 0;
}
